package com.zhuhjay.common.utils;

import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zhuhjay.common.domain.ResponseJson;
import eu.bitwalker.useragentutils.OperatingSystem;
import eu.bitwalker.useragentutils.UserAgent;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;

/**
 * Servlet工具类
 * @author ZhuHJay
 * @date 2022/3/21 21:42
 */
public class ServletUtils {

    private final static ObjectMapper MAPPER = new ObjectMapper();

    /**
     * 获取request
     */
    public static HttpServletRequest getRequest(){
        return getRequestAttributes().getRequest();
    }

    /** 获取请求的数据 **/
    public static String getParameter(String key){
        return getRequest().getParameter(key);
    }

    /**
     * 获取response
     */
    public static HttpServletResponse getResponse(){
        return getRequestAttributes().getResponse();
    }

    /** 获取session **/
    public static HttpSession getSession(){
        return getRequest().getSession();
    }

    /**
     * 获取 ServletRequestAttributes
     */
    public static ServletRequestAttributes getRequestAttributes(){
        RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
        return (ServletRequestAttributes) attributes;
    }

    /**
     * 获取 request 的请求 json数据 (缺陷, 只能获取一次, 指针不能被重置)
     */
    public static String getRequestJson() throws IOException {
        BufferedReader streamReader = new BufferedReader(
                new InputStreamReader(getRequest().getInputStream(), StandardCharsets.UTF_8)
        );
        StringBuilder responseStrBuilder = new StringBuilder();
        String inputStr;
        while ((inputStr = streamReader.readLine()) != null){
            responseStrBuilder.append(inputStr);
        }
        return responseStrBuilder.toString();
    }

    /** 获取 request 请求的 json -> map数据对象 **/
    public static JSONObject getRequestObj() throws IOException {
        return JSONObject.parseObject(getRequestJson());
    }

    /**
     * 向客户端写Json数据
     */
    public static void writeJson(HttpServletResponse response, ResponseJson message) {
        try{
            response.setContentType("application/json;charset=UTF-8");
            String json = MAPPER.writeValueAsString(message);
            response.getWriter().write(json);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /** 将对象转换为JSON字符串 **/
    public static String writeObjectAsString(Object object){
        try {
            return MAPPER.writeValueAsString(object);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return "{}";
    }

    /** 获取请求头部信息 **/
    private static String getUserAgent(){
        return getRequest().getHeader("User-Agent");
    }

    /** 获取操作系统对象 **/
    private static OperatingSystem getOperatingSystem() {
        UserAgent agent = UserAgent.parseUserAgentString(getUserAgent());
        return agent.getOperatingSystem();
    }

    /** 获取os：Windows/ios/Android **/
    public static String getOs() {
        OperatingSystem operatingSystem = getOperatingSystem();
        String osName = operatingSystem.getGroup().getName();
        return "Unknown".equals(osName) ? "非浏览器请求" : osName;
    }

    /** 获取操作系统的名字 **/
    public static String getOsName() {
        OperatingSystem operatingSystem = getOperatingSystem();
        return operatingSystem.getName();
    }

    /** 获取浏览器的名字 **/
    public static String getBorderName() {
        UserAgent userAgentObj = UserAgent.parseUserAgentString(getUserAgent());
        String name = userAgentObj.getBrowser().getName();
        return "Unknown".equals(name) ? "非浏览器请求" : name;
    }

}
